package com.zxjbyte.yiyi.extension.sse.processor;

import cn.hutool.cron.CronUtil;
import com.zxjbyte.yiyi.framework.common.cache.caffeine.impl.CaffeineCache;
import com.zxjbyte.yiyi.framework.common.domain.KVStore;
import com.zxjbyte.yiyi.extension.sse.session.SseSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

/**
 * 心跳处理器
 *
 * @Author zhangxingjia
 * @Date 2024/7/11 15:03
 * @Version: 1.0
 */
@Slf4j
public class HeartbeatProcessor {

    /**
     * 广播心跳 每隔30秒发送一次心跳包
     */
    public static void broadcastHeartbeat(){
        CronUtil.schedule("0/30 * * * * ? ", (Runnable) () -> {
            CaffeineCache<String, Map<String, KVStore>> sseSessionCache = SseSession.getSseSessionCache();
            if(!sseSessionCache.isEmpty()){
                Collection<Map<String, KVStore>> values = sseSessionCache.asMap().values();
                for(Map<String, KVStore> map : values){
                    for(KVStore sessionCache : map.values()){
                        Boolean isEnabled = sessionCache.getBool(SseSession.SseSessionKeyEnum.HEARTBEAT.name());
                        if(!Boolean.TRUE.equals(isEnabled)){
                            continue;
                        }
                        SseEmitter sseEmitter = (SseEmitter) sessionCache.get(SseSession.SseSessionKeyEnum.EMITTER.name());
                        if(sseEmitter != null){
                            // 心跳包主要用来保持连接活跃的轻量级消息
                            try {
                                sseEmitter.send(SseEmitter.event().comment("ping"));
                            } catch (IOException e) {
                                sseEmitter.completeWithError(e);
                            }
                        }
                    }
                }
            }
        });
        CronUtil.setMatchSecond(true);
        CronUtil.start();
        log.info("broadcast heartbeat >>>> start!");
    }

}
